<template>
  <div
    class="card"
    :class="cardClass"
    :style="cardStyle"
    v-bind="$attrs"
    @click="handleClick"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <!-- 卡片头部 -->
    <div v-if="showHeader" class="card-header" :class="headerClass">
      <div class="card-header-content">
        <!-- 头部左侧 -->
        <div class="card-header-left">
          <!-- 图标 -->
          <Icon v-if="icon" :name="icon" :size="iconSize" class="card-icon" />

          <!-- 标题 -->
          <div v-if="title || $slots.title" class="card-title-wrapper">
            <h3 class="card-title">
              <slot name="title">{{ title }}</slot>
            </h3>
            <p v-if="subtitle" class="card-subtitle">
              {{ subtitle }}
            </p>
          </div>
        </div>

        <!-- 头部右侧 -->
        <div v-if="$slots.extra || showActions" class="card-header-right">
          <slot name="extra"></slot>

          <!-- 操作按钮 -->
          <div v-if="showActions" class="card-actions">
            <Button
              v-for="action in actions"
              :key="action.key"
              :type="action.type || 'secondary'"
              :variant="action.variant || 'text'"
              :size="action.size || 'small'"
              :icon="action.icon"
              :disabled="action.disabled"
              :loading="action.loading"
              @click.stop="handleActionClick(action)"
            >
              {{ action.label }}
            </Button>
          </div>
        </div>
      </div>
    </div>

    <!-- 卡片封面 -->
    <div v-if="cover || $slots.cover" class="card-cover" :class="coverClass">
      <slot name="cover">
        <img
          v-if="cover"
          :src="cover"
          :alt="coverAlt || title"
          class="card-cover-image"
          @load="handleImageLoad"
          @error="handleImageError"
        />
      </slot>

      <!-- 封面遮罩 -->
      <div v-if="coverOverlay" class="card-cover-overlay">
        <slot name="cover-overlay"></slot>
      </div>
    </div>

    <!-- 卡片内容 -->
    <div class="card-content" :class="contentClass">
      <slot></slot>
    </div>

    <!-- 卡片底部 -->
    <div v-if="showFooter" class="card-footer" :class="footerClass">
      <slot name="footer"></slot>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="card-loading">
      <Loading :size="loadingSize" :type="loadingType" />
    </div>

    <!-- 选中指示器 -->
    <div v-if="selectable && selected" class="card-selected-indicator">
      <Icon name="check" :size="16" />
    </div>

    <!-- 徽章 -->
    <div v-if="badge" class="card-badge" :class="`card-badge-${badgeType}`">
      {{ badge }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import Icon from "./Icon.vue";
import Button from "./Button.vue";
import Loading from "./Loading.vue";

interface CardAction {
  key: string;
  label: string;
  icon?: string;
  type?: string;
  variant?: string;
  size?: string;
  disabled?: boolean;
  loading?: boolean;
  handler?: () => void;
}

interface Props {
  // 基础属性
  title?: string;
  subtitle?: string;
  icon?: string;

  // 封面
  cover?: string;
  coverAlt?: string;
  coverOverlay?: boolean;

  // 样式
  size?: "mini" | "small" | "medium" | "large";
  variant?: "default" | "outlined" | "filled" | "elevated" | "flat";
  shadow?: "none" | "small" | "medium" | "large";
  radius?: "none" | "small" | "medium" | "large" | "full";

  // 状态
  loading?: boolean;
  disabled?: boolean;
  hoverable?: boolean;
  clickable?: boolean;
  selectable?: boolean;
  selected?: boolean;

  // 布局
  horizontal?: boolean;
  bordered?: boolean;

  // 头部和底部
  showHeader?: boolean;
  showFooter?: boolean;

  // 操作
  actions?: CardAction[];

  // 徽章
  badge?: string | number;
  badgeType?: "default" | "primary" | "success" | "warning" | "error";

  // 加载
  loadingSize?: string;
  loadingType?: string;

  // 类名
  headerClass?: string;
  contentClass?: string;
  footerClass?: string;
  coverClass?: string;
}

const props = withDefaults(defineProps<Props>(), {
  size: "medium",
  variant: "default",
  shadow: "small",
  radius: "medium",
  hoverable: true,
  showHeader: true,
  showFooter: true,
  badgeType: "primary",
  loadingSize: "medium",
  loadingType: "spinner",
});

const emit = defineEmits<{
  click: [event: MouseEvent];
  actionClick: [action: CardAction, event: MouseEvent];
  select: [selected: boolean];
  imageLoad: [event: Event];
  imageError: [event: Event];
  mouseEnter: [event: MouseEvent];
  mouseLeave: [event: MouseEvent];
}>();

// 响应式数据
const isHovered = ref(false);

// 计算属性
const cardClass = computed(() => {
  return [
    `card-${props.size}`,
    `card-${props.variant}`,
    `card-shadow-${props.shadow}`,
    `card-radius-${props.radius}`,
    {
      "card-horizontal": props.horizontal,
      "card-bordered": props.bordered,
      "card-hoverable": props.hoverable,
      "card-clickable": props.clickable,
      "card-selectable": props.selectable,
      "card-selected": props.selected,
      "card-disabled": props.disabled,
      "card-loading": props.loading,
      "card-hovered": isHovered.value,
    },
  ];
});

const cardStyle = computed(() => {
  const styles: Record<string, string> = {};
  return styles;
});

const iconSize = computed(() => {
  const sizeMap = {
    mini: 16,
    small: 18,
    medium: 20,
    large: 24,
  };
  return sizeMap[props.size];
});

const showActions = computed(() => {
  return props.actions && props.actions.length > 0;
});

// 事件处理
const handleClick = (event: MouseEvent) => {
  if (props.disabled || props.loading) return;

  if (props.selectable) {
    emit("select", !props.selected);
  }

  emit("click", event);
};

const handleActionClick = (action: CardAction) => {
  if (action.disabled || action.loading) return;

  if (action.handler) {
    action.handler();
  }

  emit("actionClick", action, event as MouseEvent);
};

const handleMouseEnter = (event: MouseEvent) => {
  if (props.hoverable && !props.disabled) {
    isHovered.value = true;
  }
  emit("mouseEnter", event);
};

const handleMouseLeave = (event: MouseEvent) => {
  isHovered.value = false;
  emit("mouseLeave", event);
};

const handleImageLoad = (event: Event) => {
  emit("imageLoad", event);
};

const handleImageError = (event: Event) => {
  emit("imageError", event);
};
</script>

<style scoped>
/* 基础样式 */
.card {
  position: relative;
  background-color: var(--bg-color);
  border: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: all 0.2s ease;
}

/* 尺寸 */
.card-mini {
  min-height: 120px;
}

.card-small {
  min-height: 160px;
}

.card-medium {
  min-height: 200px;
}

.card-large {
  min-height: 280px;
}

/* 变体 */
.card-default {
  background-color: var(--bg-color);
  border-color: var(--border-color);
}

.card-outlined {
  background-color: transparent;
  border-color: var(--border-color);
  border-width: 2px;
}

.card-filled {
  background-color: var(--bg-secondary);
  border-color: transparent;
}

.card-elevated {
  background-color: var(--bg-color);
  border-color: transparent;
}

.card-flat {
  background-color: var(--bg-color);
  border-color: transparent;
  box-shadow: none !important;
}

/* 阴影 */
.card-shadow-none {
  box-shadow: none;
}

.card-shadow-small {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.card-shadow-medium {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-shadow-large {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

/* 圆角 */
.card-radius-none {
  border-radius: 0;
}

.card-radius-small {
  border-radius: 4px;
}

.card-radius-medium {
  border-radius: 8px;
}

.card-radius-large {
  border-radius: 12px;
}

.card-radius-full {
  border-radius: 24px;
}

/* 水平布局 */
.card-horizontal {
  flex-direction: row;
}

.card-horizontal .card-cover {
  flex-shrink: 0;
  width: 200px;
}

.card-horizontal .card-content {
  flex: 1;
}

/* 边框 */
.card-bordered {
  border-width: 2px;
}

/* 状态 */
.card-hoverable:hover:not(.card-disabled):not(.card-loading) {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.card-clickable {
  cursor: pointer;
}

.card-selectable {
  cursor: pointer;
}

.card-selected {
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px rgba(var(--primary-color-rgb), 0.2);
}

.card-disabled {
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none;
}

.card-loading {
  pointer-events: none;
}

/* 头部 */
.card-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
}

.card-header-content {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.card-header-left {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.card-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.card-icon {
  flex-shrink: 0;
  color: var(--text-secondary);
  margin-top: 2px;
}

.card-title-wrapper {
  flex: 1;
  min-width: 0;
}

.card-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-subtitle {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.4;
}

.card-actions {
  display: flex;
  gap: 4px;
}

/* 封面 */
.card-cover {
  position: relative;
  overflow: hidden;
  background-color: var(--bg-tertiary);
}

.card-cover-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.card-cover-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.6));
  display: flex;
  align-items: flex-end;
  padding: 16px;
  color: white;
}

/* 内容 */
.card-content {
  flex: 1;
  padding: 20px;
  color: var(--text-primary);
  line-height: 1.6;
}

/* 底部 */
.card-footer {
  padding: 12px 20px 16px;
  border-top: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
}

/* 加载状态 */
.card-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

/* 选中指示器 */
.card-selected-indicator {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 24px;
  height: 24px;
  background-color: var(--primary-color);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  z-index: 5;
}

/* 徽章 */
.card-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  z-index: 5;
}

.card-badge-default {
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
}

.card-badge-primary {
  background-color: var(--primary-color);
  color: white;
}

.card-badge-success {
  background-color: var(--success-color);
  color: white;
}

.card-badge-warning {
  background-color: var(--warning-color);
  color: white;
}

.card-badge-error {
  background-color: var(--error-color);
  color: white;
}

/* 尺寸变体 */
.card-mini .card-header {
  padding: 12px 16px;
}

.card-mini .card-content {
  padding: 16px;
}

.card-mini .card-footer {
  padding: 8px 16px 12px;
}

.card-mini .card-title {
  font-size: 14px;
}

.card-mini .card-subtitle {
  font-size: 12px;
}

.card-small .card-header {
  padding: 14px 18px;
}

.card-small .card-content {
  padding: 18px;
}

.card-small .card-footer {
  padding: 10px 18px 14px;
}

.card-small .card-title {
  font-size: 15px;
}

.card-large .card-header {
  padding: 20px 24px;
}

.card-large .card-content {
  padding: 24px;
}

.card-large .card-footer {
  padding: 16px 24px 20px;
}

.card-large .card-title {
  font-size: 18px;
}

/* 响应式 */
@media (max-width: 768px) {
  .card-horizontal {
    flex-direction: column;
  }

  .card-horizontal .card-cover {
    width: 100%;
    height: 200px;
  }

  .card-header-content {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .card-header-right {
    justify-content: flex-end;
  }

  .card-actions {
    flex-wrap: wrap;
  }
}

@media (max-width: 480px) {
  .card-header {
    padding: 12px 16px;
  }

  .card-content {
    padding: 16px;
  }

  .card-footer {
    padding: 10px 16px 12px;
  }

  .card-title {
    font-size: 15px;
  }
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .card-loading {
    background-color: rgba(0, 0, 0, 0.8);
  }

  .card-shadow-small {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  .card-shadow-medium {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  }

  .card-shadow-large {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  }
}

/* 无障碍支持 */
@media (prefers-reduced-motion: reduce) {
  .card {
    transition: none;
  }

  .card-hoverable:hover {
    transform: none;
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  .card {
    border-width: 2px;
  }

  .card-selected {
    border-width: 3px;
  }
}
</style>
